package client.net.sf.saxon.ce.expr.instruct; import java.util.ArrayList; import java.util.Iterator; import com.google.gwt.core.client.JavaScriptObject; import client.net.sf.saxon.ce.dom.HTMLNodeWrapper; import client.net.sf.saxon.ce.js.IXSLFunction; import client.net.sf.saxon.ce.om.Item; import client.net.sf.saxon.ce.om.SequenceIterator; import client.net.sf.saxon.ce.om.StandardNames; import client.net.sf.saxon.ce.om.ValueRepresentation; import client.net.sf.saxon.ce.pattern.EmptySequenceTest; import client.net.sf.saxon.ce.trans.XPathException; import client.net.sf.saxon.ce.type.ItemType; import client.net.sf.saxon.ce.type.Type; import client.net.sf.saxon.ce.type.TypeHierarchy; import client.net.sf.saxon.ce.expr.*; public class SetProperty extends Instruction { private Expression targetObject; private Expression name; private Expression select; /** * Create a set-property instruction - if object is null this defaults * to the window object */ public SetProperty(Expression object, Expression select, Expression name) { this.targetObject = object; this.name = name; this.select = select; adoptChildren(); } public int getInstructionNameCode() { return StandardNames.IXSL_SET_PROPERTY; } /** * Simplify an expression. This performs any static optimization (by rewriting the expression * as a different expression). The default implementation does nothing. * @param visitor an expression visitor * @return the simplified expression * @throws client.net.sf.saxon.ce.trans.XPathException * if an error is discovered during expression rewriting */ public Expression simplify(ExpressionVisitor visitor) throws XPathException { targetObject = visitor.simplify(targetObject); name = visitor.simplify(name); select = visitor.simplify(select); return this; } public Expression typeCheck(ExpressionVisitor visitor, ItemType contextItemType) throws XPathException { targetObject = visitor.typeCheck(targetObject, contextItemType); name = visitor.typeCheck(name, contextItemType); select = visitor.typeCheck(select, contextItemType); adoptChildren(); return this; } private void adoptChildren() { adoptChildExpression(select); adoptChildExpression(targetObject); adoptChildExpression(name); } public Expression optimize(ExpressionVisitor visitor, ItemType contextItemType) throws XPathException { targetObject = visitor.optimize(targetObject, contextItemType); name = visitor.optimize(name, contextItemType); select = visitor.optimize(select, contextItemType); adoptChildren(); return this; } public int getIntrinsicDependencies() { return StaticProperty.HAS_SIDE_EFFECTS; } /** * Handle promotion offers, that is, non-local tree rewrites. * @param offer The type of rewrite being offered * @throws client.net.sf.saxon.ce.trans.XPathException */ protected void promoteInst(PromotionOffer offer) throws XPathException { targetObject = doPromotion(targetObject, offer); name = doPromotion(name, offer); select = doPromotion(select, offer); } /** * Get the item type of the items returned by evaluating this instruction * @param th the type hierarchy cache * @return the static item type of the instruction. This is empty: the set-attribute instruction * returns nothing. */ public ItemType getItemType(TypeHierarchy th) { return EmptySequenceTest.getInstance(); } /** * Get all the XPath expressions associated with this instruction * (in XSLT terms, the expression present on attributes of the instruction, * as distinct from the child instructions in a sequence construction) */ public Iterator<Expression> iterateSubExpressions() { ArrayList list = new ArrayList(3); list.add(select); list.add(targetObject); list.add(name); return list.iterator(); } /** * Replace one subexpression by a replacement subexpression * @param original the original subexpression * @param replacement the replacement subexpression * @return true if the original subexpression is found */ public boolean replaceSubExpression(Expression original, Expression replacement) { boolean found = false; if (select == original) { select = replacement; found = true; } if (targetObject == original) { targetObject = replacement; found = true; } if (name == original) { name = replacement; found = true; } return found; } private static Object eval(Expression ex, XPathContext context) throws XPathException { return IXSLFunction.convertToJavaScript(ExpressionTool.evaluate(ex, ExpressionTool.ITERATE_AND_MATERIALIZE, context, 1)); } public TailCall processLeavingTail(XPathContext context) throws XPathException { Object content = eval(select, context); JavaScriptObject clientObject = (JavaScriptObject)eval(targetObject, context); String member = (String)eval(name, context); try { IXSLFunction.setProperty(clientObject, member, content); } catch (Exception e){ throw new XPathException("Error setting client-property: " + member + " " + e.getMessage()); } return null; } } // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. // If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. // This Source Code Form is “Incompatible With Secondary Licenses”, as defined by the Mozilla Public License, v. 2.0.